<!-- eslint-disable unicorn/prefer-string-replace-all -->
<script lang="ts" setup>
import { TabPane, Tabs } from 'ant-design-vue'
import { objectDeserializer } from '../../utils/internal'
import type { BodyType } from '../../types/apis/basic'

import {ref} from 'vue'
import {useGlobalConfigStore} from '../../stores/global-config.store'
import {objectSerializer} from '../../utils/internal'

const props = withDefaults(
  defineProps<{
    keyName?: string
    isStressTest?: boolean,
    isStressTestBefore?: boolean,
    disabled: boolean,
    differentFields?: Array<string>
  }>(),
  {
    keyName: 'key',
    isStressTest: false,
    isStressTestBefore: false,
    disabled: false,
    differentFields: () => [] as Array<string>
  },
)

const globalConfig = useGlobalConfigStore()
const bodyType = defineModel<BodyType>('bodyType', { required: true })

const activeKey = ref<'head' | 'body' | 'query' | string>('head')
const headDataSource = ref<object[]>([])
const queryDataSource = ref<object[]>([])
const relationDataSource = ref<object[]>([])

const textDataSource = ref<string>('')
const jsonDataSource = ref<object>({})
const pairDataSource = ref<object[]>([])
const uploadDataSource = ref<object>([])
function serialize() {
  let body = '',
    query = '',
    header = '',
    relation = ''

  if (queryDataSource.value.length > 0) {
    query = objectSerializer(queryDataSource.value).replace(
      /"name":/g,
      `"${props.keyName}":`,
    )
  }

  if (relationDataSource.value.length > 0) {
    relation = objectSerializer(relationDataSource.value)
  }
  if (bodyType.value) {
    if (
      bodyType.value.toUpperCase() === 'FORM_DATA' ||
      bodyType.value.toUpperCase() === 'X_WWW_FORM_URLENCODED'
    ) {
      body = objectSerializer(pairDataSource.value).replace(
        /"name":/g,
        `"${props.keyName}":`,
      )
    } else if (bodyType.value.toUpperCase() === 'JSON') {
      if (typeof jsonDataSource.value === 'string') {
        body = (jsonDataSource.value as string).replace(/\s/g, '')
      } else {
        body = objectSerializer(jsonDataSource.value)
      }
    } else if (bodyType.value.toUpperCase() === 'BINARY') {
      body = objectSerializer(uploadDataSource.value)
    } else {
      body = textDataSource.value
    }
  }

  if (headDataSource.value.length > 0) {
    header = objectSerializer(headDataSource.value).replace(
      /"name":/g,
      `"${props.keyName}":`,
    )
  }

  return {
    query,
    header,
    relation,
    body,
  }
}

function deserialize({
  query,
  header,
  relation,
  body,
  bodyType,
}: {
  query: string
  header: string
  relation: string
  body: string
  bodyType: BodyType
}) {

  if (query) {
    queryDataSource.value = objectDeserializer(
      query.replace(new RegExp(`"${props.keyName}":`, 'g'), `"name":`),
    )
  } else {
    queryDataSource.value = []
  }
  if (header) {
    headDataSource.value = objectDeserializer(
      header.replace(new RegExp(`"${props.keyName}":`, 'g'), `"name":`),
    )
  } else {
    headDataSource.value = []
  }
  if (relation) {
    relationDataSource.value = objectDeserializer(relation)
  } else {
    relationDataSource.value = []
  }
  if (bodyType) {
    if (bodyType.toUpperCase() === 'FORM_DATA' || bodyType.toUpperCase() === 'X_WWW_FORM_URLENCODED') {
      if(!!body && Array.isArray(JSON.parse(body))){
        pairDataSource.value = objectDeserializer(
          body.replace(new RegExp(`"${props.keyName}":`, 'g'), `"name":`), true
        )
      }else{
        pairDataSource.value =  []
      }
    } else if (bodyType.toUpperCase() === 'JSON') {
      // .replace(/\\"/g, '"') 含义是将转义【"】转化成普通【"】
      if(globalConfig.controlStepState === 'new'){
        // console.info("是new，需要转义");
        jsonDataSource.value = objectDeserializer(body.replace(/'/g, '"').replace(/\\n/g, "").replace(/\\"/g, '"'), false)
      }else if(globalConfig.controlStepState === 'edit'){
        // console.info('是edit， 无需转义，new那块已经转了，在转就错了')
        jsonDataSource.value = objectDeserializer(body.replace(/'/g, '"').replace(/\\n/g, ""), false)
      }
      
    } else if (bodyType.toUpperCase() === 'BINARY') {
      uploadDataSource.value = objectDeserializer(body, false)
    } else {
      textDataSource.value =
        body.includes('{') || body.includes('[') ? JSON.parse(body) : body
    }
  }
}

defineExpose({ 
  serialize,
  deserialize,
})

const { changeActiveKey } = storeToRefs(useRequestConfigStore()) 
const requestConfigStore = useRequestConfigStore()

watch(() => changeActiveKey, (newVal) => {
    activeKey.value = newVal.value
},{
    immediate: true,
    deep: true,
})

const chageTabs = (activeKey: string) => {
    if(props.isStressTest) return;
    requestConfigStore.setChangeActiveKey(activeKey)
}
</script>

<template>
  <Tabs v-model:active-key="activeKey" @change="chageTabs">
    <slot name="head" />
    <TabPane v-if="globalConfig.testType !== 'DATABASE'" key="head" >
      <template v-slot:tab><span :class="{'custom-label': differentFields.includes('header')}">请求头</span></template>

      <PairTable
        v-model:data-source="headDataSource"
        key-name="name"
        key-title="请求头名称"
        value-name="value"
        value-title="请求头内容"
        :disabled="disabled"
      />
    </TabPane>
    <TabPane v-if="globalConfig.testType !== 'DATABASE'" key="body" >
      <template v-slot:tab><span :class="{'custom-label': differentFields.includes('body')}">请求体</span></template>
      <RequestBody
        v-model:current="bodyType"
        v-model:text-data-source="textDataSource"
        v-model:pair-data-source="pairDataSource"
        v-model:json-data-source="jsonDataSource"
        v-model:upload-data-source="uploadDataSource"
        key-name="name"
        :is-stress-test="true"
        :disabled="disabled"
      />
    </TabPane>
    <TabPane v-if="globalConfig.testType !== 'DATABASE'" key="query" >
      <template v-slot:tab><span :class="{'custom-label': differentFields.includes('query')}">查询参数</span></template>
      <PairTable
        v-model:data-source="queryDataSource"
        key-name="name"
        key-title="查询参数名称"
        value-name="value"
        value-title="查询参数内容"
        :disabled="disabled"
      />
    </TabPane>
    <TabPane v-if="isStressTest && isStressTestBefore" key="relation" tab="关联参数">
      <PairTable
        v-model:data-source="relationDataSource"
        key-name="defaultValue"
        key-title="默认值"
        value-name="refNames"
        value-title="关联参数名称"
        extra-name="jsonPathExpressions"
        extra-title="关联参数内容"
      />
    </TabPane>

    <slot name="foot"  />
  </Tabs>
</template>

<style scoped>
.custom-label{
  color: red !important;
}
</style>